package com.aplink.generic.util;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.imagezoom.ImageAttacher;

import java.lang.ref.WeakReference;

public class FetchBitmapAysn extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private View mWaitingView;
    private boolean isThumbnail;
    private int mWidth;
    private int mHeight;
    public static final int MODE_FILE = 0;
    public static final int MODE_RESOURCE = 1;
    private Resources mResources;

    public FetchBitmapAysn( ImageView imageView, boolean isThumbnail,
                            Resources decodeFromResource ) {
        this.isThumbnail = isThumbnail;
        mResources = decodeFromResource;
        imageViewReference = new WeakReference<ImageView>( imageView );
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if ( mWaitingView != null ) {
            mWaitingView.setVisibility( View.VISIBLE );
            if ( imageViewReference.get() != null ) {
                imageViewReference.get().setVisibility( View.INVISIBLE );
            }
        }
    }

    public FetchBitmapAysn( View waitingView, ImageView imageView,
                            boolean isThumbnail, Resources decodeFromResource ) {
        imageViewReference = new WeakReference<ImageView>( imageView );
        this.isThumbnail = isThumbnail;
        mResources = decodeFromResource;
    }

    public FetchBitmapAysn( ImageView imageView, boolean isThumbnail, int width,
                            int height, Resources resources ) {
        imageViewReference = new WeakReference<ImageView>( imageView );
        this.isThumbnail = isThumbnail;
        mWidth = width;
        mHeight = height;
        mResources = resources;
    }

    public FetchBitmapAysn( View waitingView, ImageView imageView,
                            boolean isThumbnail, int width, int height, Resources resources ) {
        imageViewReference = new WeakReference<ImageView>( imageView );
        this.isThumbnail = isThumbnail;
        mWidth = width;
        mHeight = height;
        mResources = resources;
        mWaitingView = waitingView;
    }

    @Override
    protected Bitmap doInBackground( String... params ) {
        String imageUrl = params[0];
        int resId = AndroidUIParser.getDrawableIdByName( imageUrl );
        if ( isThumbnail ) {
            if ( mResources == null ) {
                return decodeThumbnailBitmapFromFile( imageUrl );
            }
            return decodeThumbnailBitmapFromResource( mResources, resId );
        }
        if ( mResources == null ) {
            return decodeSampledBitmapFromFile( imageUrl, mWidth, mHeight );
        }
        return decodeSampledBitmapFromResource( mResources, resId, mWidth,
                mHeight );

    }

    @Override
    protected void onPostExecute( Bitmap bitmap ) {
        if ( imageViewReference != null && bitmap != null ) {
            final ImageView imageView = imageViewReference.get();
            if ( imageView != null ) {
                imageView.setImageBitmap( bitmap );
                setZoomEvent( imageView );
            }
        }
    }

    public void setZoomEvent( ImageView imageView ) {
        final ImageAttacher mAttacher = new ImageAttacher( imageView );
        ImageAttacher.MAX_ZOOM = 2.5f; // Double the current Size
        ImageAttacher.MIN_ZOOM = 1f; // Half the current Size
        mAttacher.setScaleType( ScaleType.CENTER_INSIDE );
    }

    private int calculateInSampleSize( BitmapFactory.Options options,
                                       int reqWidth, int reqHeight ) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if ( ( height > reqHeight ) || ( width > reqWidth ) ) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            while ( ( ( halfHeight / inSampleSize ) > reqHeight )
                    && ( ( halfWidth / inSampleSize ) > reqWidth ) ) {
                inSampleSize *= 2;
            }

            long totalPixels = ( width * height ) / inSampleSize;

            final long totalReqPixelsCap = reqWidth * reqHeight * 2;

            while ( totalPixels > totalReqPixelsCap ) {
                inSampleSize *= 2;
                totalPixels /= 2;
            }
        }
        return inSampleSize;
    }

    private BitmapFactory.Options getDefaultOptions() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.inDither = false;
        options.inJustDecodeBounds = false;
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];
        return options;
    }

    public Bitmap decodeSampledBitmapFromFile( String filename, int reqWidth,
                                               int reqHeight ) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile( filename, options );
        getDefaultOptions().inSampleSize = calculateInSampleSize( options,
                reqWidth, reqHeight );
        return BitmapFactory.decodeFile( filename, getDefaultOptions() );
    }

    public Bitmap decodeThumbnailBitmapFromFile( String filename ) {
        return decodeSampledBitmapFromFile( filename, 320, 240 );
    }

    public Bitmap decodeThumbnailBitmapFromResource( Resources res, int resId ) {
        return decodeSampledBitmapFromResource( res, resId, 320, 240 );
    }

    public Bitmap decodeSampledBitmapFromResource( Resources res, int resId,
                                                   int reqWidth, int reqHeight ) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource( res, resId, options );
        getDefaultOptions().inSampleSize = calculateInSampleSize( options,
                reqWidth, reqHeight );
        return BitmapFactory.decodeResource( res, resId, getDefaultOptions() );
    }

    public View getLoadingView() {
        return mWaitingView;
    }

    public void setLoadingView( View loadingView ) {
        mWaitingView = loadingView;
    }

}
